/*
 *  dna_cloud.h -- provide dna-system clouds management.
 *  
 *  Clouds operation method, as follows:
 *
 *     @ SET interface, used for set device status
 *     @ GET interface, used for get device status
 *     @ UPLOAD interface, used for upload device data (such as device status)
 * 
 *  Based on the above, multiple clouds can be unified abstraction and process.
 *
 *  Error code please refer to dna_errno.h
 *
 *  ORIGINAL AUTHOR: Xu Chun (chun.xu@broadlink.com.cn)
 *
 *  Copyright (c) 2016 Broadlink Corporation
 */

#ifndef __DNA_CLOUD_H
#define __DNA_CLOUD_H

#include "dna_cloudparam.h"
#include "dna_cloudtask.h"
#include "dna_wlan.h"

#ifdef __cplusplus
    extern "C" {
#endif

#define DNA_CLOUD_ID(name)                           DNA_CLOUD_##name
#define DNA_CLOUD_ENABLE(name)                       BIT(DNA_CLOUD_ID(name))

/* dna-system cloud platform smartconfig status code */
typedef enum {
    DNA_CLOUD_SMTCFG_CONTINUE        = 0,
    DNA_CLOUD_SMTCFG_CHANNEL_LOCKED,
    DNA_CLOUD_SMTCFG_CHANNEL_UNLOCK,
    DNA_CLOUD_SMTCFG_DONE,
#ifdef CONFIG_FASTCON_CLOUD
	DNA_CLOUD_SMTCFG_FASTCON,
#endif
} dna_smtcfg_status_e;

/* dna-system cloud platform device data format code */
typedef enum {
    DNA_CLOUD_DEVDATA_BINARY    = 0,                /*!<  Standard binary */
    DNA_CLOUD_DEVDATA_KEYVALUE,
    DNA_CLOUD_DEVDATA_PASSTHROUGH,
    DNA_CLOUD_DEVDATA_PRODUCT_CUSTOM,
    DNA_CLOUD_DEVDATA_FASTCON_BYPASS,
} dna_cloud_devdata_format_e;

#ifdef CONFIG_SUPPORT_DNA_GATEWAY
/* dna-system cloud platform device data work mode */
typedef enum {
	DNA_CLOUD_DEVSNAPSHOT_GET = 0,
	DNA_CLOUD_DEVSNAPSHOT_SET,
	DNA_CLOUD_DEVSNAPSHOT_BYPASS
} dna_cloud_devdata_work_e;

typedef enum {
	DNA_CLOUD_GATEWAY_FUNC_PROBE_START = 1,
	DNA_CLOUD_GATEWAY_FUNC_PROBE_STOP,
	DNA_CLOUD_GATEWAY_FUNC_PROBE_LIST,
	DNA_CLOUD_GATEWAY_FUNC_ADD,
	DNA_CLOUD_GATEWAY_FUNC_DEL,
	DNA_CLOUD_GATEWAY_FUNC_LIST,
	DNA_CLOUD_GATEWAY_FUNC_PWD_SET,
	DNA_CLOUD_GATEWAY_FUNC_PWD_GET,
	DNA_CLOUD_GATEWAY_FUNC_EDIT,
	DNA_CLOUD_GATEWAY_FUNC_ADD_RESULT,
	DNA_CLOUD_GATEWAY_FUNC_MARK,
	DNA_CLOUD_GATEWAY_FUNC_GW_TYPE,
	DNA_CLOUD_GATEWAY_FUNC_RESET,
	DNA_CLOUD_GATEWAY_FUNC_UPLOAD,
	DNA_CLOUD_GATEWAY_FUNC_SUBSCRIBE_ADD,
	DNA_CLOUD_GATEWAY_FUNC_SUBSCRIBE_DEL,
	DNA_CLOUD_GATEWAY_FUNC_SUBSCRIBE_LIST,
	DNA_CLOUD_GATEWAY_FUNC_SUBSCRIBE_PUSH,
	DNA_CLOUD_GATEWAY_FUNC_SUBSCRIBE_ALL,
	DNA_CLOUD_GATEWAY_FUNC_VERSION,
} dna_cloud_gateway_func_e;
#endif

/* dna-system cloud platform server connect status code */
typedef enum {
    DNA_CLOUD_SERV_CONNECTING        = 0, 
    DNA_CLOUD_SERV_CONNECT_SUCCESS,                 /*!<  Keep heartbeat */
    DNA_CLOUD_SERV_DNS_TIMEOUT,
    DNA_CLOUD_SERV_CONNECT_TIMEOUT,
    DNA_CLOUD_SERV_HEARTBEAT_TIMEOUT,
    DNA_CLOUD_SERV_CONNECT_FAULT,
} dna_cloud_serv_status_e;

/* dna-system cloud platform data upload type code */
typedef enum {
    DNA_CLOUD_PERIOD_UPLOAD          = 0,
    DNA_CLOUD_TRIGGER_UPLOAD,
    DNA_CLOUD_ACTIVE_UPLOAD,
    DNA_CLOUD_METER_UPLOAD,
#ifdef CONFIG_BL_FASTCON
	DNA_CLOUD_AUDIO_UPLOAD, 	/*!< fastcon use audio bypass upload */
#endif    
	DNA_CLOUD_FAULT_UPLOAD,                        /*!< Such as device fault or abnormal */
} dna_cloud_upload_type_e;

/* dna-system now support cloud ID list */
typedef enum {
    DNA_CLOUD_BROADLINK              = 0,
    DNA_CLOUD_JOYLINK,
    DNA_CLOUD_WECHAT,
    DNA_CLOUD_ALINK,
    DNA_CLOUD_GIZWITS,
    DNA_CLOUD_HAIER,
    DNA_CLOUD_GALANZ,
    DNA_CLOUD_HILINK,
    DNA_CLOUD_MSMART,
    DNA_CLOUD_GREE,
    DNA_CLOUD_SUNING,    
    DNA_CLOUD_GOME,
    DNA_CLOUD_TCL,
	DNA_CLOUD_ANDLINK,
	DNA_CLOUD_AUX,
	DNA_CLOUD_QQLINK,
	DNA_CLOUD_FASTCON,
    DNA_CLOUD_TELECOM_ZJ,
    DNA_CLOUD_LINKKIT,
	DNA_CLOUD_BAIDU,
	DNA_CLOUD_ELINK,
	DNA_CLOUD_SIMPFC,
    DNA_CLOUD_VIRTUAL,
} dna_cloud_id_e;

/* dna-system cloud platform system data manage operation code */
typedef enum {
    DNA_CLOUD_SYSDATA_ADD            = 0,
    DNA_CLOUD_SYSDATA_DEL,
    DNA_CLOUD_SYSDATA_SET,
    DNA_CLOUD_SYSDATA_GET,
} dna_cloud_sysdata_opt_e;

/* dna-system cloud platform system data type code.
*   0 - 31 --> system reserved, not change !!!
*   >31    --> user custom
*/
typedef enum {
    DNA_CLOUD_SYSDATA_TIMERTASK      = 0,
    DNA_CLOUD_SYSDATA_CLOUDMENU,
    DNA_CLOUD_SYSDATA_DEVICE,                      /*!<  Contain sub-device */
    DNA_CLOUD_SYSDATA_OTA,
    DNA_CLOUD_SYSDATA_MSG_PUSH,                    /*!<  Such as JPUSH and Homing pigeon */
    DNA_CLOUD_SYSDATA_PAR_UPDATE,                  /*!<  Such as joylink uuid or suning model update*/   
    DNA_CLOUD_SYSDATA_EARLY_RESPONSE,
#ifdef CONFIG_BL_FASTCON
    DNA_CLOUD_SYSDATA_AUDIO,        /* Fastcon audio upload directly */
#endif
#ifdef CONFIG_DNA_LOGDUMP_MODULE
    DNA_CLOUD_SYSDATA_LOG,
#endif
#ifdef CONFIG_FASTCON_BRIDGE
    DNA_CLOUD_SYSDATA_BRIDGE,       /* Fastcon bridge */
#endif
} dna_cloud_sysdata_type_e;

/* dna-system cloud platform system data device type code */
typedef enum {
    DNA_CLOUD_SYSDATA_MAIN_DEVICE    = 0,
    DNA_CLOUD_SYSDATA_SUB_DEVICE,
} dna_cloud_sysdata_devtype_e;

/* dna-system cloud platform system data device operation code */
typedef enum {
    DNA_CLOUD_SYSDATA_DEV_UNBIND     = 0,
} dna_cloud_sysdata_devopt_e;

/* dna-system config network mode code */
enum network_config_e{
	DNA_NETWOEK_CONFIG_SMTCFG_AP,
	DNA_NETWOEK_CONFIG_SMTCFG,
	DNA_NETWOEK_CONFIG_AP,
  DNA_NETWOEK_CONFIG_AP_SMTCFG,
	DNA_NETWOEK_CONFIG_MAX,
};

/* 
*  dna-system cloud platform get running patameters callback interface.
*/
typedef int (* dna_get_param_cb_t)(
                   /* Cloud ID: refer to dna_cloud_id_e */
                   unsigned int cloud_id,
                   void * buffer, unsigned int maxsize);

/* 
*  dna-system cloud platform device control callback interface.
*/
typedef int (* dna_device_control_cb_t)(
                   /* Cloud ID: refer to dna_cloud_id_e */
                   unsigned int cloud_id,
                   /* Control mode: refer to dna_cloud_devdata_format_e */
                   unsigned int mode,
#ifdef CONFIG_SUPPORT_DNA_GATEWAY
				   /* Operation mode: refer to dna_cloud_devdata_work_e */
				   unsigned int opcode,
				   /* Repeat request */
				   unsigned int repeat,
#endif
                   /*
                              *  Input and output: standard binary / keyvalue / passthrough format.
                              *  If len set to 0, then means that get device latest status.
                              */
                   const unsigned char * input, unsigned int len,
                   unsigned char * output, unsigned int maxsize);

#ifdef CONFIG_SUPPORT_DNA_GATEWAY
/*
 * dna-system cloud platform gateway function callback interface.
 */
typedef int (* dna_gateway_func_cb_t)(
					/* Cloud ID: refer to dna_cloud_id_e */
					unsigned int cloud_id,
					/* Gateway func mode: refer to dna_cloud_gateway_func_e */
					unsigned int mode,
					/* Input and output: passthrough data. */
					const unsigned char * input, unsigned int len,
					unsigned char * output, unsigned int maxsize);
#endif

/*
*  dna-system cloud platform system data manage callback interface.
*/
typedef int (* dna_sysdata_manage_cb_t)(
                   /* Sysdata type: 0 - timertask, 1 - cloudmenu
                              (refer to dna_cloud_sysdata_type_e) */
                   unsigned int type,
                   /* Sysdata opcode: refer to dna_cloud_sysdata_opt_e */
                   unsigned int opcode,
                   /* Cloud ID: refer to dna_cloud_id_e */
                   unsigned int cloud_id,
                   const unsigned char * input, unsigned int len,
                   unsigned char * output, unsigned int maxsize);

/* dna-system cloud platform network configuration handler */
typedef struct dna_cloud_netcfg_handler {
    /* Smartconfig mode */
    int (* smt_init)(void);
    int (* smt_deinit)(void);
    /* Parse result (>= 0 on success):  refer to dna_smtcfg_status_e */
    int (* smt_parse)(const void * frame, unsigned short len, unsigned char channel);
    int (* smt_done)(dna_wifi_network_t * network);
    int (* smt_reset)(void);
	int (* smt_lock)(void);
	int (* smt_fail_notify)(int fail_reason);
    /* Soft-ap mode */
    int (* ap_start)(dna_wifi_network_t * network);
    int (* ap_stop)(void);
} dna_cloud_netcfg_handler_t;

/* dna-system cloud descriptor */
typedef struct dna_cloud_desc {
    /* Cloud initialize and uninitialize */
    int (* init)(void);
    int (* run)(void);
    int (* deinit)(void);
    /* Get cloud platform server connect status (return >= 0 on success),
      *  Please refer to dna_cloud_serv_status_e.
      */
    int (* get_connect_status)(void);
    /* Get cloud platform device control package sequence status.
      *  If return TRUE, then means that the control is a retry action.
      */
    int (* get_seq_status)(void);
    /* 
      *  Cloud platform device data upload.
      *
      *  @type: 0 - period upload, 1 - trigger upload, 2 - active upload, 3 - fault upload
      *  (refer to dna_cloud_upload_type_e)
      *  @mode: data format (refer to dna_cloud_devdata_format_e)
      */
    int (* data_upload)(unsigned int type, unsigned int mode, const unsigned char * data, unsigned int len);
    /* 
       *  Cloud platform system data change (such as OTA upgrade progress) upload.
       *
       *  @type: system data type, refer to dna_cloud_sysdata_type_e.
       */
    int (* mgt_upload)(unsigned int type, const unsigned char * data, unsigned int len);
    /* Cloud platform network configuration support */
    dna_cloud_netcfg_handler_t netcfg_handle;
} dna_cloud_desc_t;

/*
*  dna-system start smartconfig on WLAN sniffer mode,
*  This function used to catch 802.11 packet, then parsing SSID and PSK.
*
*  @network: the network configuration information
*  @timeout: smartconfig max keep time (seconds), if set 0, then forever, until stop or success
*
*  Notice: this function will blocking current task.
*
*  Return cloud unique ID (>=0) if successful;
*            -DNA_E_SMTCFG_TIMEOUT if timeout;
*            -DNA_E_SMTCFG_STOP if stop;
*            -DNA_E_INVAL if input param invalid.
*/
int dna_cloud_smartcfg_start(
        dna_wifi_network_t * network,
        unsigned int timeout);

/*
*  dna-system stop smartconfig on WLAN sniffer mode.
*
*  Return 0 means stop smartcfg success.
*/
int dna_cloud_smartcfg_stop(void);

/*
*  dna-system smartconfig on fixed channel.
*
*  @channel: fixed channel (CH1-CH13)
*  Return 0 on success.
*/
int dna_cloud_smartcfg_set_channel(unsigned char channel);

/*
*  dna-system smartconfig country type set interface.
*
*  @country_type: 0 (CH1-CH13, default) / 1 (CH1-CH11)
*  Return 0 on success.
*/
int dna_cloud_smartcfg_set_country_type(unsigned char country_type);

/*
*  dna-system soft-ap mode network configuration start.
*  It depends on the specific cloud, so must provide cloud unique ID.
*  WiFi module inspire a LAN hotspots, then user can connect it and send target network
*  Information to it.
*
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*  @network: the network configuration information (such as SSID/PSK)
*
*  Notice: this function will blocking current task.
*
*  Return DNA_SUCCESS if start successful;
*          -DNA_FAIL if start fail or stop;
*          -DNA_E_INVAL if input param invalid.
*/
int dna_cloud_apcfg_start(
        unsigned int cloud_id,
        dna_wifi_network_t * network);

/*
*  dna-system soft-ap mode network configuration stop.
*  If dna_cloud_apcfg_start was running, then another task call this interface, will
*  Break off APConfig, then dna_cloud_apcfg_start will return.
*  
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*
*  Return 0 means APConfig stop success, otherwise fail.
*/
int dna_cloud_apcfg_stop(unsigned int cloud_id);

/*
*  dna-system cloud platform data upload interface.
*
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*  @type: 0 - period upload, 1 - trigger upload, 2 - active upload, 3 - fault upload
*  (refer to dna_cloud_upload_type_e)
*  @mode: data format (refer to dna_cloud_devdata_format_e)
*  @input: input data (standard binary or keyvalue or passthrough)
*  @len: input data valid length
*
*  Return 0 means data upload success.
*/
int dna_cloud_data_upload(
        unsigned int cloud_id,
        unsigned int type, unsigned int mode,
        const unsigned char * input, unsigned int len);

/*
*  dna-system cloud platform mgt upload (such as OTA upgrade progress) interface.
*
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*  @type: system data type (refer to dna_cloud_sysdata_type_e)
*  @input: input data
*  @len: input data valid length
*
*  Return 0 means mgt upload success.
*/
int dna_cloud_mgt_upload(
        unsigned int cloud_id, unsigned int type,
        const unsigned char * input, unsigned int len);

/*
*  dna-system cloud platform device control callback interface register.
*
*  @handle: device control callback interface
*
*  Return 0 means callback interface register success.
*/
int dna_cloud_control_register(dna_device_control_cb_t handle);

#ifdef CONFIG_SUPPORT_DNA_GATEWAY
/*
 * dna-system cloud platform gateway function callback interface register.
 *
 * @handle: gateway function callback interface
 *
 * Return 0 means callback interface register success.
 */
int dna_cloud_gateway_register(dna_gateway_func_cb_t handle);
#endif

/*
*  dna-system cloud platform system data manage callback interface register.
*
*  @handle: system data manage callback interface
*
*  Return 0 means callback interface register success.
*/
int dna_cloud_manage_register(dna_sysdata_manage_cb_t handle);

/*
*  dna-system get cloud platform server connect status interface.
*
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*
*  Return cloud platform server connect status.
*/
int dna_cloud_connect_status(unsigned int cloud_id);

/*
*  dna-system get cloud platform device control package sequence status.
*
*  @cloud_id: cloud unique identifier (refer to dna_cloud_id_e)
*
*  Notice: you maybe need to call the interface to prevent device repeated action
*  When device control in poor network.
*
*  Return TRUE means the control package is a retry action.
*/
int dna_cloud_seq_status(unsigned int cloud_id);

/*
*  dna-system cloud platform dynamic register interface.
*
*  @cloud: cloud descriptor
*
*  Return cloud unique ID (> 0) means register success, if return <0 means register error.
*/
int dna_cloud_register(dna_cloud_desc_t * cloud);

/*
*  dna-system cloud dynamic unregister interface.
*
*  @cloud_id: cloud unique ID
*
*  Return 0 means unregister success, if return <0 means unregister error.
*/
int dna_cloud_unregister(unsigned int cloud_id);

/*
*  dna-system the specified cloud startup interface.
*
*  @cloud_id: cloud unique ID
*
*  Return 0 means startup success
*/
int dna_cloud_start(unsigned int cloud_id);

/*
*  dna-system the specified cloud stop interface.
*
*  @cloud_id: cloud unique ID
*
*  Return 0 means stop success
*/
int dna_cloud_stop(unsigned int cloud_id);

/*
*  dna-system multiple clouds batch startup interface.
*
*  @mask: multiple clouds MASK
*
*  Return 0 means batch startup success
*
*  Notice: this interface only used to start system static registered clouds.
*/
int dna_cloud_batch_start(unsigned int mask);

/*
*  dna-system multiple clouds batch stop interface.
*
*  Return 0 means batch stop success
*
*  Notice: this interface only used to stop system static registered clouds,
*  Correspond with dna_cloud_batch_start.
*/
int dna_cloud_batch_stop(void);

/*
*  dna-system multiple clouds startup according to the config options.
*  (Such as make menuconfig)
*
*  Return 0 means clouds startup success
*
*  Notice: this interface apply to startup current valid clouds (static and dynamic).
*/
void dna_cloud_startup(void);

/*
*  Four New APIs, they apply to cloud platform defer startup (or running).
*  Usage scenario:  New APIs provides defer startup mechanism, it is mainly to more reasonable
*  Allocate memory resources when system memory is not ample.
*  Most of the tasks are starting to work only after the network connected, 
*  So we can create these tasks when network connected, avoid resource competition
*  With network mangement task (such as network config and connecting).
*/

/* <I>
*  dna-system the specified cloud initialization interface.
*
*  @cloud_id: cloud unique ID
*
*  Return 0 on success.
*/
int dna_cloud_single_init(unsigned int cloud_id);

/* <II>
*  dna-system the specified cloud running interface.
*
*  @cloud_id: cloud unique ID
*
*  Return 0 on success.
*/
int dna_cloud_single_run(unsigned int cloud_id);

/* <III>
*  dna-system multiple clouds batch initialization interface.
*
*  @mask: multiple clouds MASK
*
*  Return 0 means batch init success
*
*  Notice: this interface only used to initialize system static registered clouds.
*/
int dna_cloud_batch_init(unsigned int mask);

/* <IV>
*  dna-system multiple clouds batch running interface.
*
*  @mask: multiple clouds MASK
*
*  Return 0 means batch running success
*
*  Notice: this interface only used to running system static registered clouds.
*/
int dna_cloud_batch_run(unsigned int mask);

/*
*  Four New APIs, they are used for get or check cloud platform init or run status.
*  1) dna_cloud_get_init_mask: get initialized mask (only used for static registered clouds)
*  2) dna_cloud_get_run_mask: get ran mask (only used for static registered clouds)
*  3) dna_cloud_is_init (TRUE or FALSE)
*  4) dna_cloud_is_run (TRUE or FALSE)
*/
int dna_cloud_get_init_mask(void);
int dna_cloud_get_run_mask(void);
int dna_cloud_is_init(unsigned int cloud_id);
int dna_cloud_is_run(unsigned int cloud_id);

#ifdef DNA_CLOUD_CONNECT_HEALTHMON

/*
*  dna-system cloud servers connection status health monitor.
*  dna_cloud_connect_healthmon Return TRUE means that healthful, 
*  Otherwise, means that at least One cloud server is offline for a long time (default: 180s).
*/
int dna_cloud_connect_healthmon(void);
int dna_cloud_connect_healthmon_set(unsigned int mask);
int dna_cloud_connect_healthmon_enable(unsigned int cloud_id);
int dna_cloud_connect_healthmon_disable(unsigned int cloud_id);
int dna_cloud_connect_healthmon_reset(void);

#else

#define dna_cloud_connect_healthmon()           TRUE
#define dna_cloud_connect_healthmon_set(a)
#define dna_cloud_connect_healthmon_enable(a)
#define dna_cloud_connect_healthmon_disable(a)
#define dna_cloud_connect_healthmon_reset()

#endif

/*
*  dna-system multiple clouds management initialization.
*
*  @handle: get cloud platform running parameters callback interface
*
*  Return 0 means initialize success, if return <0 means occurred error.
*/
int dna_cloud_init(dna_get_param_cb_t handle);

/*
*  dna-system network config start.
*
*  @handle: start connect the network by connect mode(0:smcfg 1:cmcfg+ap 2:ap)
*
*  Return DNA_SUCCESS if start successful;
*         -DNA_FAIL if start fail or stop;
*         -DNA_E_INVAL if input param invalid.
*/
int dna_cloud_network_config_start(unsigned int cloud_id, dna_wifi_network_t * network,
        unsigned char netcfg_mode, unsigned short netcfg_timeout,
        void (* netcfg_notify)(int status));

#ifdef __cplusplus
}
#endif

#endif

